home *** CD-ROM | disk | FTP | other *** search
- //
- // The Fusion Library Interface for DOS
- // Version 1.06c
- // Copyright (C) 1990, 1991, 1992
- // Software Dimensions
- //
- // MenuControl --> MenuItems --> FusionWindow
- //
-
- #include "fliwin.h"
- #include "colors.h"
-
- #ifdef __BCPLUSPLUS__
- #pragma hdrstop
- #endif
-
- #include <alloc.h>
- #include <string.h>
-
- int MenuManager::IdentifyCheck=1;
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // MenuItems()
- //
- // Constructor for MenuItems class
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- MenuItems::MenuItems()
- {
- Title=0;
- MenuHelp=0;
- MenuHotKey=0;
- CurrentOption=0;
- NumberOfOptions=0;
- SubMenus=0;
- HotKeys=0;
- Width=0;
- Height=2;
- X=0;
- Y=0;
- XStart=0;
- XEnd=0;
- SavedRegion=0;
- Option=0;
- Checkables=0;
- Selectables=0;
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // ~MenuItems()
- //
- // Destructor for MenuItems class
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- MenuItems::~MenuItems()
- {
- if (NumberOfOptions)
- {
- for (int i=0;i<NumberOfOptions;i++)
- {
- if ((Option+i)->SubMenu)
- delete (Option+i)->SubMenu;
- if ((Option+i)->Selectables)
- delete (Option+i)->Selectables;
- }
- free(Option);
- }
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // PlaceMenu()
- //
- // Places a menu on the display
- //
- // The Refreshing variable is used to refresh a menu and does not save
- // the insides, its primary purpose is to redraw ONLY the inside of the menu
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- int MenuItems::PlaceMenu(int SetY,int CurrentLevel,MenuItems &PreviousMenu,
- int Refreshing)
- {
- BlazeClass Blaze;
-
- if (!Refreshing)
- {
- if (!Option)
- {
- Blaze.HelpLine(0,(!MenuEvent)?"Menu not available":MenuHelp);
- MouseHide();
- Blaze.ChangeBackground(XStart,SetY,XEnd-XStart+1,1,Colors.MenuHiLite);
- MouseShow();
- CurrentLevel++;
- X=500;
- Y=500;
- return 0;
- }
- }
-
- MouseHide();
- Blaze.InvisibleCursor();
-
- Width=0;
-
- Height=NumberOfOptions+2;
-
- for (int j=0,_OWide=0,_HWide=0,_SWide=0,_CWide=0,_EWide=0,OkaySubs=0;
- j<Height-2;j++)
- {
- _Options &Option=*(MenuItems::Option+j);
-
- Option.PreviousState=(Option.Available)?*Option.Available:1;
-
- int OWide=(strlen(Option.Option)-(strchr(Option.Option,'~')?1:0));
- int HWide=(Option.HotKeyOption)?(strlen(Option.HotKeyOption)+1):0;
- int SWide=(Option.SubMenu)?2:0;
- int CWide=(Option.Checked)?2:0;
- int EWide=0;
-
- if (Option.SelectCount)
- {
- for (int i=0,Widest=0,Width;i<Option.SelectCount;i++)
- {
- if ((Width=strlen(Option.Selectables[i]))>Widest)
- Widest=Width;
- }
- Option.WidestSelectable=EWide=++Widest;
- }
-
- if (Option.SubMenu && !Option.Checked && !Option.Selectables)
- OkaySubs++;
-
- if (OWide>_OWide)
- _OWide=OWide;
- if (HWide>_HWide)
- _HWide=HWide;
- if (SWide>_SWide)
- _SWide=SWide;
- if (CWide>_CWide)
- _CWide=CWide;
- if (EWide>_EWide)
- _EWide=EWide;
- }
-
- Width=(_OWide+_HWide+_SWide+_CWide+_EWide+5)-((OkaySubs && Selectables)?2:0);
-
- if (Checkables && Selectables)
- {
- if (_EWide>_CWide)
- Width-=_CWide;
- else
- Width-=_EWide;
- }
-
- if (!Refreshing)
- {
- if (CurrentLevel==1)
- {
- Blaze.ChangeBackground(XStart,SetY,XEnd-XStart+1,1,Colors.MenuHiLite);
-
- X=(XStart+Width+1>Blaze.WhatWidth()-1)?(Blaze.WhatWidth()-Width):XStart;
- Y=(SetY+Height>Blaze.WhatHeight()-2)?(Blaze.WhatHeight()-Height-1):(SetY+1);
- }
- else
- {
- if (!MenuManager::Beneath)
- {
- Y=PreviousMenu.Y+PreviousMenu.CurrentOption;
- X=PreviousMenu.X+PreviousMenu.Width;
- }
- else
- {
- Y=PreviousMenu.Y+PreviousMenu.CurrentOption+2;
- X=PreviousMenu.X+2;
- }
-
- X=(X+Width>=Blaze.WhatWidth())?(Blaze.WhatWidth()-Width):X;
- Y=(Y+Height>Blaze.WhatHeight()-2)?(Blaze.WhatHeight()-Height-1):Y;
- }
-
- if (FusionShadowing)
- {
- int XShadow=1;
- int YShadow=1;
-
- int XOffset=0;
- int YOffset=0;
-
- if (X+Width==Blaze.WhatWidth())
- {
- XShadow=0;
- XOffset=1;
- }
-
- if (Y+Height==Blaze.WhatHeight()-2)
- {
- YShadow=0;
- YOffset=1;
- }
-
- SavedRegion=new char[Blaze.ComputeNeededBytes(Width+XShadow,Height+YShadow)];
-
- Blaze.GetArea(X,Y,Width+XShadow,Height+YShadow,SavedRegion);
- Blaze.Shadow(X+XShadow+XOffset,Y+YShadow+YOffset,Width,Height);
- }
- else
- {
- SavedRegion=new char[Blaze.ComputeNeededBytes(Width,Height)];
-
- Blaze.GetArea(X,Y,Width,Height,SavedRegion);
- }
- }
-
- if (!Refreshing || Refreshing==2)
- {
- Blaze.Box(X,Y,Width,Height,Colors.MenuBorder);
- Blaze.EraseArea(X+1,Y+1,Width-2,Height-2,Colors.MenuInsides);
- }
-
- for (j=0;j<Height-2;j++)
- {
- _Options &Option=*(MenuItems::Option+j);
-
- if (Refreshing && Refreshing!=2)
- {
- if (j==CurrentOption &&
- (!Option.Available || (Option.Available && *Option.Available)))
- continue;
-
- if (j==CurrentOption && Option.Available && !*Option.Available)
- Blaze.CharacterRepeater(X+1,Y+1+j,Width-2,Colors.MenuInsides,32);
- }
-
- if (Option.Option)
- {
- Option.QuickKey=Blaze.QuickDisplay(X+2+((Checkables)?2:0),Y+1+j,
- (*Option.Available)?Colors.MenuQuickKey:Colors.MenuDeadOption,
- (*Option.Available)?Colors.MenuInsides:Colors.MenuDeadOption,
- Option.Option);
- if (Checkables && Option.Checked)
- Blaze (X+2,Y+1+j) <<
- ((*Option.Available)?Colors.MenuCheckMark:Colors.MenuDeadOption) <<
- (char)((*Option.Checked)?'˚':((MenuManager::IdentifyCheck)?'_':' '));
- else
- if (Selectables && Option.Selectables)
- {
- Blaze (X+Width-2-strlen(Option.Selectables[*Option.Selectable]),Y+1+j) <<
- ((*Option.Available)?Colors.MenuSelectable:Colors.MenuDeadOption) <<
- Option.Selectables[*Option.Selectable];
- }
- if (Option.HotKeyOption)
- {
- Blaze
- ((X+Width-strlen(Option.HotKeyOption)-2-((SubMenus)?2:0)-
- ((Selectables)?_EWide:0)),
- Y+1+j)
- << ((*Option.Available)?Colors.MenuHotKey:Colors.MenuDeadOption)
- << Option.HotKeyOption;
- }
- if (Option.SubMenu && !Option.Checked)
- {
- Blaze (X+Width-3,Y+1+j)
- << ((*Option.Available)?Colors.MenuSubPointer:Colors.MenuDeadOption)
- << ((MenuManager::Beneath)?'\x1f':'\x10');
- }
- }
- else
- {
- Blaze.CharacterRepeater(X+1,Y+1+j,
- Width-2,Colors.MenuBorder,196);
- Blaze << Colors.MenuBorder;
- Blaze (X,Y+1+j) << '\xc3';
- Blaze (X+Width-1,Y+1+j) << '\xb4';
- }
- }
-
- if (Refreshing)
- {
- if (!(Option+CurrentOption)->Available ||
- ((Option+CurrentOption)->Available && *(Option+CurrentOption)->Available))
- PlaceOption(CurrentOption);
- else if ((Option+CurrentOption)->Available &&
- !*(Option+CurrentOption)->Available)
- {
- RemoveOption();
- int i=-1;
- int j=0;
- do i=(i==NumberOfOptions-1)?0:(++i);
- while ((!*(Option+i)->Available ||
- !(Option+i)->Option) &&
- ++j!=NumberOfOptions);
- PlaceOption(i);
- }
-
- return 0;
- }
- else
- return PlaceOption(CurrentOption);
- }
-
- void MenuItems::ReCheckOption()
- {
- MouseHide();
- BlazeClass Blaze;
- Blaze (X+2,Y+1+CurrentOption) << Colors.MenuCheckMark <<
- (char)((*(Option+CurrentOption)->Checked)?'˚':
- ((MenuManager::IdentifyCheck)?'_':' '));
- PlaceOption(CurrentOption);
- }
-
- void MenuItems::ReSelectOption()
- {
- MouseHide();
- BlazeClass Blaze;
- _Options &Option=*(MenuItems::Option+CurrentOption);
- Blaze.CharacterRepeater(X+Width-Option.WidestSelectable-1,Y+1+CurrentOption,
- Option.WidestSelectable-3,Colors.DiaInterior,' ');
- Blaze (X+Width-2-strlen(Option.Selectables[*Option.Selectable]),Y+1+CurrentOption) <<
- ((*Option.Available)?Colors.MenuSelectable:Colors.MenuDeadOption) <<
- Option.Selectables[*Option.Selectable];
- PlaceOption(CurrentOption);
- }
-
- void MenuManager::PlaceMenu(MenuItems &Menu)
- {
- SubMenuTrack=(MenuItems**)realloc(SubMenuTrack,sizeof(MenuItems*)*++CurrentLevel);
- SubMenuTrack[CurrentLevel-1]=&Menu;
-
- HelpId=Menu.PlaceMenu(SetY,CurrentLevel,*SubMenuTrack[CurrentLevel-2]);
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // PlaceOption()
- //
- // Places an option back on the menu
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- int MenuItems::PlaceOption(int OptionToPlace)
- {
- if (!NumberOfOptions)
- return 0;
-
- BlazeClass Blaze;
-
- _Options &Option=*(MenuItems::Option+OptionToPlace);
- CurrentOption=OptionToPlace;
-
- MouseHide();
-
- if (!*Option.Available)
- Blaze.HelpLine(0,"Option not available");
- else if (!Option.Option)
- Blaze.HelpLine(0,"Not an option");
- else
- {
- Blaze.ChangeBackground(X+1,Y+OptionToPlace+1,Width-2,1,Colors.MenuHiLite);
- Blaze.HelpLine(Option.Event,Option.Help);
- }
-
- MouseShow();
-
- return (!*Option.Available || !Option.Option)?0:Option.Event;
- }
-
- void MenuManager::PlaceOption(int OptionToPlace)
- {
- HelpId=SubMenuTrack[CurrentLevel-1]->PlaceOption(OptionToPlace);
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // RemoveMenu()
- //
- // Removes a menu from the display
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- void MenuItems::RemoveMenu()
- {
- BlazeClass Blaze;
-
- MouseHide();
-
- if (SavedRegion)
- {
- Blaze.PutArea(X,Y,SavedRegion);
- delete SavedRegion;
- SavedRegion=0;
- }
-
- Blaze.HelpLine(0,"");
-
- MouseShow();
- }
-
- void MenuManager::RemoveMenu()
- {
- if (CurrentLevel)
- CurrentLevel--;
- else
- return;
-
- MenuItems &Menu=*SubMenuTrack[CurrentLevel];
-
- Menu.RemoveMenu();
-
- if (!CurrentLevel)
- {
- MouseHide();
- BlazeClass Blaze;
- Blaze.ChangeBackground(Menu.XStart,SetY,Menu.XEnd-Menu.XStart+1,1,
- Colors.MenuBarNormal);
- MouseShow();
- }
-
- if (CurrentLevel)
- {
- MenuItems &Menu=*SubMenuTrack[CurrentLevel-1];
- _Options &Option=*(Menu.Option+Menu.NumberOfOptions-1);
- HelpId=Option.Event;
- }
- else
- HelpId=0;
-
- return;
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // RemoveOption()
- //
- // Removes highlighting from an option
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- void MenuItems::RemoveOption()
- {
- if (!NumberOfOptions)
- return;
-
- BlazeClass Blaze;
-
- _Options &Option=*(MenuItems::Option+CurrentOption);
-
- if (!*Option.Available || !Option.Option)
- return;
-
- MouseHide();
- Blaze.ChangeBackground(X+1,Y+1+CurrentOption,Width-2,1,Colors.MenuInsides);
- MouseShow();
- }
-
- void MenuManager::RemoveOption()
- {
- if (!CurrentLevel)
- return;
-
- SubMenuTrack[CurrentLevel-1]->RemoveOption();
-
- HelpId=0;
-
- return;
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // ScanMenu()
- //
- // Scan menu for a hot key
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- int MenuItems::ScanMenu(int Event)
- {
- for (int i=0;i<NumberOfOptions;i++)
- {
- _Options &Option=*(MenuItems::Option+i);
-
- if (Event==Option.HotKey)
- {
- if (*Option.Available && Option.Checked && Option.Option)
- {
- *Option.Checked=(*Option.Checked)?0:1;
- return Option.Event;
- }
-
- if (!*Option.Available || !Option.Option)
- return 0;
-
- if (Option.SubMenu)
- continue;
-
- if (Option.Checked)
- *Option.Checked=(*Option.Checked)?0:1;
- else
- if (Option.Selectables)
- *Option.Selectable=(*Option.Selectable==Option.SelectCount-1)?0:(++(*Option.Selectable));
-
- return Option.Event;
- }
-
- }
-
- for (i=0;i<NumberOfOptions;i++)
- {
- _Options &Option=*(MenuItems::Option+i);
-
- if (Option.SubMenu)
- {
- if (!*Option.Available || !Option.Option)
- continue;
-
- int Save=Option.SubMenu->ScanMenu(Event);
-
- if (Save)
- return Save;
- }
- }
-
- return 0;
- }
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- //
- // RefreshMenus()
- //
- // Refreshes the Menus -- if they have changed
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- void MenuManager::RefreshMenus()
- {
- if (!CurrentLevel)
- return;
-
- for (int i=0;i<CurrentLevel;i++)
- {
- for (int j=0;j<SubMenuTrack[i]->NumberOfOptions;j++)
- {
- _Options &Option=*(SubMenuTrack[i]->Option+j);
-
- if (Option.Available && Option.PreviousState!=*Option.Available)
- {
- // Menu State HAS Changed!!
-
- MenuItems DudMenu;
-
- if (i==CurrentLevel-1) // On bottom menu tree
- SubMenuTrack[i]->PlaceMenu(0,0,DudMenu,1);
- else // Within the menu tree
- {
- // Scan the tree and see if any menus should be trimmed off
-
- for (int q=i;q<CurrentLevel;q++)
- {
- _Options &Option=*(SubMenuTrack[q]->Option+
- SubMenuTrack[q]->CurrentOption);
-
- if (!Option.Available || (Option.Available && *Option.Available))
- continue; // This level is acceptable
- else
- {
- // whoops! An option isn't available! Trim off remaining branches
-
- int TrimOff=CurrentLevel-q;
-
- for (int s=0;s<TrimOff-1;s++)
- RemoveMenu();
-
- if (q!=i)
- for (int r=i;r<CurrentLevel;r++)
- SubMenuTrack[r]->PlaceMenu(0,0,DudMenu,2);
-
- if (CurrentLevel)
- SubMenuTrack[CurrentLevel-1]->PlaceMenu(0,0,DudMenu,1);
-
- // Browse through menus and knock off menus that are all dead
-
- for (s=CurrentLevel-1;s>=0;s--)
- {
- for (int r=0,t=0;r<SubMenuTrack[s]->NumberOfOptions;r++)
- {
- _Options &Option=*(SubMenuTrack[s]->Option+r);
-
- if ((!Option.Available ||
- (Option.Available && *Option.Available)) &&
- Option.Option)
- t++;
- }
- if (!t)
- RemoveMenu();
- }
-
- return;
- }
- }
-
- for (q=i;q<CurrentLevel;q++)
- SubMenuTrack[q]->PlaceMenu(0,0,DudMenu,2);
-
- return;
- }
-
- return;
- }
- }
- }
- }
-
-